package com.yokead;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.LineHandler;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.qiniu.cdn.CdnManager;
import com.qiniu.cdn.CdnResult;
import com.qiniu.util.Auth;
import com.yokead.common.QiNiuUtil;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbMakerConfigException;
import org.lionsoul.ip2region.DbSearcher;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.zip.GZIPInputStream;

/**
 * Created by jiangzeyin on 2018/10/16.
 */
public class GetIp {

    static DbConfig config;

    static {
        try {
            config = new DbConfig();
        } catch (DbMakerConfigException e) {
            e.printStackTrace();
        }
    }

    static DbSearcher searcher;

    static {
        try {
            searcher = new DbSearcher(config, "D:\\ide\\YOKEAD_Order\\admin\\src\\test\\java\\data\\ip2region.db");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static Set<String> getip(DateTime date, int dayCount) throws Exception {
        Auth auth = QiNiuUtil.getAuth();
        CdnManager c = new CdnManager(auth);
        //域名列表
        String[] domains = new String[]{"adimg1.yokead.com"};
        File parent = new File("/var/log");
        Set<String> cdnMap = new HashSet<>(2000);
        Calendar calendar = date.toCalendar();
        calendar.add(Calendar.DATE, -1);
        for (int i = 0; i < dayCount; i++) {
            calendar.add(Calendar.DATE, 1);
            String logDate = DateTime.of(calendar).toString(DatePattern.NORM_DATE_PATTERN);
            System.out.println(logDate);
            //
            CdnResult.LogListResult logListResult = c.getCdnLogList(domains, logDate);
            Map<String, CdnResult.LogData[]> map = logListResult.data;
            Collection<CdnResult.LogData[]> collection = map.values();
            for (CdnResult.LogData[] logDatas : collection) {
                for (CdnResult.LogData logData : logDatas) {
                    File file = new File(parent, logData.name);
                    HttpUtil.downloadFile(logData.url, file);
                    FileInputStream fin = new FileInputStream(file);
                    //建立gzip解压工作流
                    GZIPInputStream gzipInputStream = new GZIPInputStream(fin);
                    IoUtil.readLines(gzipInputStream, CharsetUtil.CHARSET_UTF_8, (LineHandler) line -> {
                        String[] logs = line.replace("\"", "").split(" ");
                        String ip = logs[0];
                        try {
                            DataBlock dataBlock = searcher.binarySearch(ip);
                            if (!dataBlock.getRegion().startsWith("中国")) {
                                System.out.println(dataBlock + "  " + ip);
                                String[] ips = StrUtil.splitToArray(ip, '.');
                                ip = ips[0] + "." + ips[1] + "." + ips[2] + ".1/24";
                                cdnMap.add(ip);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    });
                }
            }
        }
        return cdnMap;
    }

    public static Object[] getCdn(DateTime date, int dayCount) throws Exception {
        Auth auth = QiNiuUtil.getAuth();
        CdnManager c = new CdnManager(auth);
        //域名列表
        String[] domains = new String[]{"adimg1.yokead.com"};
        File parent = new File("/var/log");
        Map<String, Long> cdnMap = new HashMap<>(200);
        Map<String, Map<String, Long>> urlIp = new HashMap<>(200);
        Calendar calendar = date.toCalendar();
        calendar.add(Calendar.DATE, -1);
        for (int i = 0; i < dayCount; i++) {
            calendar.add(Calendar.DATE, 1);
            String logDate = DateTime.of(calendar).toString(DatePattern.NORM_DATE_PATTERN);
            System.out.println(logDate);
            //
            CdnResult.LogListResult logListResult = c.getCdnLogList(domains, logDate);
            Map<String, CdnResult.LogData[]> map = logListResult.data;
            Collection<CdnResult.LogData[]> collection = map.values();
            for (CdnResult.LogData[] logDatas : collection) {
                for (CdnResult.LogData logData : logDatas) {
                    File file = new File(parent, logData.name);
                    HttpUtil.downloadFile(logData.url, file);
                    FileInputStream fin = new FileInputStream(file);
                    //建立gzip解压工作流
                    GZIPInputStream gzipInputStream = new GZIPInputStream(fin);
                    Map<String, Long> finalCdnMap = cdnMap;
                    IoUtil.readLines(gzipInputStream, CharsetUtil.CHARSET_UTF_8, (LineHandler) line -> {
                        String[] logs = line.replace("\"", "").split(" ");
                        String url = logs[10];
                        Long val = finalCdnMap.computeIfAbsent(url, s -> 0L);
                        val += Long.valueOf(logs[9]);
                        finalCdnMap.put(url, val);
                        //
                        String ip = logs[0];
                        Map<String, Long> iPMap = urlIp.computeIfAbsent(url, s -> new HashMap<>(100));
                        Long oldVal = iPMap.computeIfAbsent(ip, s -> 0L);
                        iPMap.put(ip, oldVal + 1);
                    });
                }
            }
        }
        cdnMap = sortMapByValue(cdnMap);
        Set<Map.Entry<String, Long>> entries = cdnMap.entrySet();
        int count = 0;
        long total = 0L;
        for (Map.Entry<String, Long> entry : entries) {
            long val = entry.getValue();
            total += val;
            if (count++ < 50) {
                System.out.print(entry.getKey() + "  ");
                System.out.println(FileUtil.readableFileSize(val));
                System.out.println(sortMapByValue(urlIp.get(entry.getKey())));
            }
        }
        System.out.println(cdnMap.size() + "  " + FileUtil.readableFileSize(total));
        return new Object[]{cdnMap, urlIp};
    }

    public static Map<String, Long> sortMapByValue(Map<String, Long> oriMap) {
        if (oriMap == null || oriMap.isEmpty()) {
            return null;
        }
        Map<String, Long> sortedMap = new LinkedHashMap<>();
        List<Map.Entry<String, Long>> entryList = new ArrayList<>(oriMap.entrySet());
        entryList.sort((o1, o2) -> o2.getValue().compareTo(o1.getValue()));

        Iterator<Map.Entry<String, Long>> iterator = entryList.iterator();
        Map.Entry<String, Long> tmpEntry;
        while (iterator.hasNext()) {
            tmpEntry = iterator.next();
            sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
        }
        return sortedMap;
    }
}
